/*
 * Copyright (C) 2019-2024 Alexander Borisov
 *
 * Author: Alexander Borisov <borisov@lexbor.com>
 */

#include "lexbor/encoding/encoding.h"
#include "lexbor/encoding/multi.h"


#define append_to_file(fc, data, len, codepoint)                               \
    do {                                                                       \
        lxb_char_t *data_to = data;                                            \
                                                                               \
        for (size_t j = 0; j < len; j++) {                                     \
            fprintf(fc, "\\x%02X", (unsigned) data_to[j]);                     \
        }                                                                      \
                                                                               \
        fprintf(fc, " 0x%04X\n", (unsigned) codepoint);                        \
    }                                                                          \
    while (0)


int main(int argc, const char * argv[])
{
    size_t size;
    lxb_char_t data[8];
    lxb_status_t status;
    lxb_encoding_encode_t ctx;
    lxb_codepoint_t cp;
    const lxb_codepoint_t *p;
    const lxb_encoding_data_t *enc_data;

    const char *filepath = "./big5_map_decode.txt";

    enc_data = lxb_encoding_data(LXB_ENCODING_BIG5);

    FILE *fc = fopen(filepath, "w");
    if (fc == NULL) {
        printf("Failed to opening file: %s\n", filepath);
        exit(EXIT_FAILURE);
    }

    fprintf(fc, "#\n"
            "# Copyright (C) 2019-2024 Alexander Borisov\n"
            "#\n"
            "# Author: Alexander Borisov <borisov@lexbor.com>\n"
            "#\n\n");

    fprintf(fc, "#\n"
            "# This file generated by the program\n"
            "# \"utils/lexbor/encoding/big5_map_decode.c\"\n"
            "#\n\n");

    /* Single index */
    size = sizeof(lxb_encoding_multi_big5_map) / sizeof(lxb_codepoint_t);

    for (size_t i = 0; i < size; i++) {
        /*
         * https://encoding.spec.whatwg.org/#index-big5-pointer
         *
         * Let index be index Big5 excluding all entries whose pointer is less
         * than (0xA1 - 0x81) × 157.
         */
        if (i < (0xA1 - 0x81) * 157) {
            continue;
        }

        p = &lxb_encoding_multi_big5_map[i];
        cp = *p;

        if (cp == LXB_ENCODING_ERROR_CODEPOINT) {
            continue;
        }

        lxb_encoding_encode_init(&ctx, enc_data, data, sizeof(data));

        status = enc_data->encode(&ctx, &p, (p + 1));
        if (status != LXB_STATUS_OK) {
            printf("Failed to encoding code point: 0x%04X; Status %d\n",
                   cp, status);
            return EXIT_FAILURE;
        }

        append_to_file(fc, ctx.buffer_out, ctx.buffer_used, cp);
    }

    fprintf(fc, "\n# END\n");

    fclose(fc);

    return EXIT_SUCCESS;
}
